<?php
class PStorage
{

   // this function links user (jos_users) information storage resume table 
   // FIXME: use user_id in oc_resumes table in jobseeker app to list all applied job positions 
   public static function setResumeStorageUserId($user) {
      // $user must have name, email, phone(if applicable) and sex 
      $hashkey = self::getResumeStorageHash($user); 

   }

   public static function getResumeStorageInfo($jobseeker_id=0) {
      if(!$resume_id)
         return null;

      $db = PFactory::getDbo();
      $query = "SELECT r.*" .
               " FROM *PREFIX*resumes AS r " .
               " LEFT JOIN *PREFIX*hr_jobseeker AS j ON j.resume_id=r.id " .
               " WHERE j.id = " . intval($jobseeker_id);

      /* try to load from cache */
      $cache = CacheHelper::getCache('app_resumes');
      // get cached data now 
      $data = $cache->call(array('PStorage', '_getResumeStorageInfo'), $query);

      // Event Driven Cache/Object Caching
      // there are the tables which we need to invoke cache cleaning triggers when tables are changed by user - Event Driven Cache/Object Caching
      if(CacheHelper::needTriggers($cache) && $data) {
         CacheHelper::setTriggers(PFactory::getMasterUser()->id, $cache, array('*PREFIX*resumes-'.$data->id));
      }

      return $data;
   }

   public static function getResumeStorageInfoById($resume_id=0) {
      if(!$resume_id)
         return null;

      $db = PFactory::getDbo();
      $query = "SELECT r.*, COUNT(j.resume_id) AS numjobseekers " .
               " FROM *PREFIX*resumes AS r " .
               " LEFT JOIN *PREFIX*hr_jobseeker AS j ON j.resume_id=r.id " .
               " WHERE r.id = " . intval($resume_id) . " GROUP BY r.id";

      /* try to load from cache */
      $cache = CacheHelper::getCache('app_resumes');
      // get cached data now 
      $data = $cache->call(array('PStorage', '_getResumeStorageInfo'), $query);

      // Event Driven Cache/Object Caching
      // there are the tables which we need to invoke cache cleaning triggers when tables are changed by user - Event Driven Cache/Object Caching
      if(CacheHelper::needTriggers($cache) && $data) {
         CacheHelper::setTriggers(PFactory::getMasterUser()->id, $cache, array('*PREFIX*resumes-'.$data->id));
      }

      return $data;
   }

   public static function getResumeStorageInfoByHashKey($hash='') {
      if(!$hash)
         return null;

      $db = PFactory::getDbo();
      $query = "SELECT r.*, COUNT(j.resume_id) AS numjobseekers " .
               " FROM *PREFIX*resumes AS r " .
               " LEFT JOIN *PREFIX*hr_jobseeker AS j ON j.resume_id=r.id " .
               " WHERE r.hashkey= " . $db->quote($hash) . " GROUP BY r.id";

      /* try to load from cache */
      $cache = CacheHelper::getCache('app_resumes');
      // get cached data now 
      $data = $cache->call(array('PStorage', '_getResumeStorageInfo'), $query);

      // Event Driven Cache/Object Caching
      // there are the tables which we need to invoke cache cleaning triggers when tables are changed by user - Event Driven Cache/Object Caching
      if(CacheHelper::needTriggers($cache) && $data) {
         CacheHelper::setTriggers(PFactory::getMasterUser()->id, $cache, array('*PREFIX*resumes-'.$data->id));
      }

      return $data;
   }

   public static function _getResumeStorageInfo($query) {
      $db = PFactory::getDbo();
      $db->setQuery(PUtil::replaceOCPrefix($query));
      return $db->loadObject();
   }

   public static function deleteResumeStorageInfo($resume_id=0) {
      if(!$resume_id)
         return;

      $db = PFactory::getDbo();
      $query = "DELETE FROM *PREFIX*resumes WHERE id = " . intval($resume_id);
      $db->setQuery(PUtil::replaceOCPrefix($query));
      $db->execute();
      CacheHelper::triggerRemove(PFactory::getMasterUser()->id, array('*PREFIX*resumes-'.$resume_id));
   }


   // get resume version 
   // a version is created based on name, email, phone, and latest_workexp_company_name. 
   // if all 4 params are same, but total workexp_months are different, we can overwrite the resume text file 
   // the oc_resumes table will keep a latest copy among all version. 
   // for a given resume, we will only keep latest 3 version per source. 
   public static function getResumeVersion($resume=null) {
      if(!$resume)
         return 0; 

      $string = '';
      if(is_object($resume)) {
        if(!isFakeEmail($resume->email))
            $string .= "," . $resume->email;

         if(JobHelper::isPhone($resume->phone))
            $string .= "," . $resume->phone;

         if($resume->latest_workexp_company_name)
            $string .= "," . $resume->latest_workexp_company_name;
      }
      elseif (is_array($resume)) {
        if(!isFakeEmail($resume['email']))
            $string .= "," . $resume['email'];

         if(JobHelper::isPhone($resume['phone']))
            $string .= "," . $resume['phone'];

         if(!empty($resume['latest_workexp_company_name']))
            $string .= "," . $resume['latest_workexp_company_name'];
      }

      
      return $string ? shortHash($string, 3, '12345679') : 0;
   }
 
   // get resume hash based on certain attributes 
   public static function getResumeStorageHash($resume=null) {
      if(!$resume)
         return null; 

      // a resume md5 hash is based on name, sex  email or phone.  The email and phone should be valid. 
      // when email or phone is changed, the relative hashkey will be changed, so it's stored location 

      $string = '';

      if(is_object($resume)) {
         if(!$resume->name || !$resume->sex)
            return null; 

         $string = $resume->name . ',' . $resume->sex; 

         // we only pick email or phone as part of hashkey, if email is not provided, phone will be used. This also means different phone might 
         // might create multiple record. 
         if(!isFakeEmail($resume->email)) 
            $string .= "," . $resume->email; 
         else if(JobHelper::isPhone($resume->phone)) 
            $string .= "," . $resume->phone; 
         else {
            // if this resume doesn't have valid email or phone, we cannot record it into our db 
            return null; 
         }
      }
      elseif (is_array($resume)) {
         if(empty($resume['name']) || empty($resume['sex']))
            return null; 

         $string = $resume['name'] . ',' . $resume['sex']; 

         // we only pick email or phone as part of hashkey, if email is not provided, phone will be used. This also means different phone might 
         // might create multiple record. 
         if(!isFakeEmail($resume['email'])) 
            $string .= "," . $resume['email']; 
         else if(JobHelper::isPhone($resume['phone'])) 
            $string .= "," . $resume['phone']; 
         else {
            // if this resume doesn't have valid email or phone, we cannot record it into our db 
            return null; 
         }
      }
      

      return $string ? md5($string) : null; 
   }

   // get resume path based on hashkey. If it doesn't exist, create it if it's told 
   public static function getResumeStoragePath($hashkey=null, $create=false) {
      if(!$hashkey)
         return null; 

      // we only need to get first 6 chars to create two-char path directory list: 
      // /aa/bb/cc/dd/<hashkey>/source/version>/
      $path  = OC::$SERVERROOT."/data/resumes/" .
               $hashkey[0].$hashkey[1]. "/" . 
               $hashkey[2].$hashkey[3]. "/" . 
               $hashkey[4].$hashkey[5]. "/" . 
               $hashkey[6].$hashkey[7]. "/" . 
               $hashkey;

      if($create && !file_exists($path)) 
         mkdir_recursive($path); 

      return $path; 
   }

   public static function getResumeStorageVersionPath($resume=null, $create=false) {
      if(!$resume)
         return null; 

      $hashpath = self::getResumePath($resume, false); 

      if(!$hashpath || !is_dir($hashpath))
         return null; 

      $versionpath = $path . $resume->source . "/" . ($resume->version ? $resume->version : "latest");
      
      if($create && !file_exists($versionpath)) 
         mkdir_recursive($versionpath); 

      return $versionpath; 
   }

   public static function storeResumePath($resume=null) {


   }

   // when a resume key is changed, we need to copy over old resume to new location to be same with new hash keys 
   public static function copyResumeStoragePath($resume=null, $newhash=null) {
      if(!$resume || !$resume->hashkey || !$newhash)
         return false; 

      $oldpath = self::getResumeStoragePath($resume->hashkey); 
      if(!is_dir($oldpath))
         return false; 

      $newpath = self::getResumeStoragePath($newhash, true); 
      if(!is_dir($newpath))
         return false; 

      execTimeout("/bin/cp -rf $oldpath/*  $newpath/");

      return true; 
   }

   // storage resume can only be removed only when there is no reference in jobseeker tables 
   public static function removeResumeStoragePath($resume=null) {
     if(!$resume || !$resume->hashkey)
         return false;

      $path = self::getResumeStoragePath($resume->hashkey);

      if(!is_dir($path))
         return false; 

      execTimeout("/bin/rm -rf $path");

      return true;
   }

   // search resume file - $resume is jobseeker object with storage_path and version 
   public static function getResumeFilePath($companyid, $resume, $source) {
      if(!$companyid || !$resume || !$source) 
         return null; 

      // check if a list of source is needed 
      if(strpos($source, ",") !== false) {
         // a list of array 
         $sources = explode(",", $source); 
         $resumefiles = array(); 
         foreach($sources as $s) {
            $path = self::getResumeFilePath($companyid, $resume, $s); 
            if($path)
               $resumefiles = array_merge($resumefiles, $path); 
         }

         return $sesumefiles; 
      }

   
      // a path is:  aa/bb/cc/<hash key>/<version>/<source>/resume.html. For a upload file, it has company id to deferentiate each upload 
      $resumefile = $resume->storage_path . "/" . $resume->version . "/" . $source . "/" . ($source == 'upload' ? $companyid : '') . "/resume.html";

      if(!file_exists($resumefile)) {
         // try latest resume. for upload, don't do this way 
         if($source != 'upload')
            $resumefile = $resume->storage_path . "/" . $resume->latest_version . "/" . $source . "/resume.html";

         if(!file_exists($resumefile)) {
            // for backward-compatibility, we try to see if there is a resume in company resume folder 
            $datadir = getUserDataDir($companyid);
            $extdir = getUserExtDir($companyid);
            $resumefile = OC::$SERVERROOT."/data".$datadir."/company/"."/".$companyid."/resumes/".$resume->id."/".$source."/resume.html";
            if(!file_exists($resumefile)) {
               // last try, might be here too when we migrate the storage 
               $resumefile = OC::$SERVERROOT."/data".$datadir."/company/".$extdir."/resumes/".$resume->id."/".$source."/resume.html";
               if(!file_exists($resumefile)) 
                  return null; 
             }
         }
  
      }

      // this one should be valid resume file 
      return array($resumefile); 
   }
}
